#include "types.h"
pentaminos_vector* Initialization(){

//X
longvector* X = new longvector;
X->push_back(0x403804000000000LLU);
//I
longvector* I = new longvector;
 I->push_back(0x802008020080000LLU);
 I->push_back(0xf80000000000000LLU);


 //Z
 longvector* Z = new longvector;
 Z->push_back(0xc01006000000000LLU);
 Z->push_back(0x60100c000000000LLU);
 Z->push_back(0x203808000000000LLU);
 Z->push_back(0x803802000000000LLU);


//U
longvector* U = new longvector;
 U->push_back(0xa03800000000000LLU);
 U->push_back(0xe02800000000000LLU);
 U->push_back(0xc0200c000000000LLU);
 U->push_back(0xc0100c000000000LLU);
//T
longvector* T = new longvector;
 T->push_back(0xe01004000000000LLU);
 T->push_back(0x40100e000000000LLU);
 T->push_back(0x203802000000000LLU);
 T->push_back(0x803808000000000LLU);
//W
longvector* W = new longvector;
 W->push_back(0x803006000000000LLU);
 W->push_back(0x20180c000000000LLU);
 W->push_back(0x603008000000000LLU);
 W->push_back(0xc01802000000000LLU);
//V
longvector* V = new longvector;
 V->push_back(0x80200e000000000LLU);
 V->push_back(0x20080e000000000LLU);
 V->push_back(0xe02008000000000LLU);
 V->push_back(0xe00802000000000LLU);
 //F
 longvector* F = new longvector;
  F->push_back(0x603004000000000LLU);
  F->push_back(0xc01804000000000LLU);
  F->push_back(0x403808000000000LLU);
  F->push_back(0x403802000000000LLU);
  F->push_back(0x803804000000000LLU);
  F->push_back(0x40180c000000000LLU);
  F->push_back(0x403006000000000LLU);
  F->push_back(0x203804000000000LLU);
  //L
 longvector* L = new longvector;
  L->push_back(0x802008030000000LLU);
  L->push_back(0x401004030000000LLU);
  L->push_back(0xf00400000000000LLU);
  L->push_back(0xf02000000000000LLU);
  L->push_back(0x103c00000000000LLU);
  L->push_back(0xc01004010000000LLU);
  L->push_back(0xc02008020000000LLU);
  L->push_back(0x803c00000000000LLU);
 //N
 longvector* N = new longvector;
  N->push_back(0x403008020000000LLU);
  N->push_back(0x803004010000000LLU);
  N->push_back(0x703000000000000LLU);
  N->push_back(0xe00c00000000000LLU);
  N->push_back(0xc01c00000000000LLU);
  N->push_back(0x40100c020000000LLU);
  N->push_back(0x80200c010000000LLU);
  N->push_back(0x303800000000000LLU);
 //P
 longvector* P = new longvector;
  P->push_back(0x40300c000000000LLU);
  P->push_back(0x80300c000000000LLU);
  P->push_back(0x603800000000000LLU);
  P->push_back(0xc03800000000000LLU);
  P->push_back(0xe01800000000000LLU);
  P->push_back(0xc03008000000000LLU);
  P->push_back(0xc03004000000000LLU);
  P->push_back(0xe03000000000000LLU);

 //Y
longvector* Y = new longvector;
 Y->push_back(0x403004010000000LLU);
 Y->push_back(0x803008020000000LLU);
 Y->push_back(0x403c00000000000LLU);
 Y->push_back(0x203c00000000000LLU);
 Y->push_back(0xf01000000000000LLU);
 Y->push_back(0x80200c020000000LLU);
 Y->push_back(0x40100c010000000LLU);
 Y->push_back(0xf00800000000000LLU);


pentaminos_vector* m_rotations=new pentaminos_vector;

m_rotations->push_back(X);//1

m_rotations->push_back(I);//2


m_rotations->push_back(Z);//4
m_rotations->push_back(U);
m_rotations->push_back(T);
m_rotations->push_back(W);
m_rotations->push_back(V);

m_rotations->push_back(F);//8
m_rotations->push_back(N);
m_rotations->push_back(P);
m_rotations->push_back(L);
m_rotations->push_back(Y);

return m_rotations;

}
/*

 This is python script used to generate initialization of vector of rotations

import string
import copy
from collections import deque

init_dict={'X':'403804000000000',
           'I':'802008020080000',
           'T':'E01004000000000',
           'U':'A03800000000000',
           'V':'80200E000000000',
           'W':'803006000000000',
           'Z':'C01006000000000',
           'L':'802008030000000',
           'N':'403008020000000',
           'P':'40300C000000000',
           'Y':'403004010000000',
           'F':'603004000000000'}


def IntToDD(intdd):
    bitstring=string.zfill(bin(intdd)[2:],60)
    separate=[bitstring[10*(i):10*(i+1)] for i in range(6)]
    dseparate=deque(separate)
    ddseparate=map(deque,dseparate)
    dddseparate=deque(ddseparate)
    return dddseparate

def HMirror(toproc):
    result=copy.deepcopy(toproc)
    map(deque.reverse,result)
    return result


def VMirror(toproc):
    result=copy.deepcopy(toproc)
    result.reverse()
    return result


def ScrollToTop(dd):
    result=copy.deepcopy(dd)
    while (tuple(result[0])==('0','0','0','0','0','0','0','0','0','0')):
        result.rotate(-1)
    return result

def ScrollToLeft(dd):
    result=copy.deepcopy(dd)
    flag= True;
    for element in result:
        flag=flag & (element[0]=='0')
    while (flag):
        for element in result:
            element.rotate(-1)
            flag=flag & (element[0]=='0')

    return result


def DDToInt(dd):
    result=copy.deepcopy(dd)
    longstring=""
    tempstring=""
    for el in range(6):
        tempstring=""
        longstring=longstring + tempstring.join(tuple(result[el]))
    return int(longstring,2)


def Transp5(in_deq):
    dddc=IntToDD(0)
    ld=map(list,dddc)
    inl=map(list,in_deq)
    for i in range(5):
        for j in range(5):
            ld[j][5-i]=inl[i][j]
    dl=map(deque,ld)
    ddl=deque(dl)
    return ddl


def norm(ddin):
    return ScrollToLeft(ScrollToTop(ddin))

def CreateRotations(int_rot):
    ddint_rot=IntToDD(int_rot)
    CSH=norm(HMirror(ddint_rot))
    CSV=norm(VMirror(ddint_rot))
    Ci=norm(HMirror(VMirror(ddint_rot)))
    C4=norm(Transp5(ddint_rot))
    CSHC4=norm(Transp5(CSH))
    CSVC4=norm(Transp5(CSV))
    CiC4=norm(Transp5(Ci))

    dd_rot_list=(ddint_rot,CSH,CSV,Ci,C4,CSHC4,CSVC4,CiC4)
    rot_list_int=map(DDToInt,dd_rot_list)
    rot_set=set(rot_list_int) # Deleting duplicating items
    return tuple(rot_set)

rotations_dict={};

for pent in init_dict.keys():
    print '#'+pent
    rotations_dict[pent]=CreateRotations(int(init_dict[pent],16))
    print "longvector* "+ pent+'= new longvector;'
    for el in rotations_dict[pent]:
        print " "+pent+"->push_back("+hex(el)+'LLU);'

*/


